package pers.cl.dubbo.gateway;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import pers.cl.dubbo.gateway.channel.HttpServerInitializer;

/**
 * @author chenlei
 * @date 2020/1/9
 * @description 启动类
 * @see pers.cl.dubbo.gateway.annotation.EnableMVC
 * @see pers.cl.dubbo.gateway.selector.EnableMVCImportRegistrar
 **/
public class GatewayApplication implements ApplicationListener<ContextRefreshedEvent>,ApplicationContextAware {

    private ApplicationContext applicationContext;

    private final static int DEFAULT_SERVER_PORT=8080;

    private static int port;

    public void start(ApplicationContext context){
        port = DEFAULT_SERVER_PORT;
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try{
            ServerBootstrap server = new ServerBootstrap();
            server.group(bossGroup,workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new HttpServerInitializer(context))
                    .option(ChannelOption.SO_BACKLOG,128)
                    .childOption(ChannelOption.SO_KEEPALIVE,true);
            ChannelFuture future = server.bind(port).sync();
            future.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    //实现ApplicationListener 指定ContextRefreshedEvent
    //作用是监听当所有bean初始化完成之后的事件触发
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        start(this.applicationContext);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
